﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ACC.Extensions.Utilities
{
    public class ComScanner
    {
        private bool connect = false;
        public ComScanner()
        {
            //logger = LogFactory.GetLog(LogFactory.DEFAULT_LOG, typeof(ComScanner).ToString());
        }

        public Boolean IsOk
        {
            get {
                try
                {
                    if (null != scannerPort && scannerPort.IsOpen)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (Exception)
                {
                    return false;
                }
            }
        }

        public delegate void BCReadHandle(String bc);
        public event BCReadHandle OnBCRead;

        public delegate void BCStatusHandle(bool connect);
        public event BCStatusHandle OnBCStatusChanged;

        public void FireOnBCRead(String BC)
        {

            //去掉回车符号
            if (BC.EndsWith("\r"))
            {
                BC = BC.Remove(BC.Length - 1);
            }

            //if (logger.IsDebugEnabled)
            //    logger.Debug(String.Format("Read BC: {0}", BC));
            if (null == OnBCRead)
                return;
            new Thread(new ThreadStart(delegate()
            {
                OnBCRead(BC);
            })).Start();
        }

        SerialPort scannerPort;
        public void Init(string portName, string baudRate, string parity, string dataBits, string stopBits)
        {
            try
            {
                // 波特率
                int iBaudRate = 0;
                if (!int.TryParse(baudRate, out iBaudRate))
                {
                    iBaudRate = 11520;
                }

                // 奇偶检验
                int iParity = 0;
                if (!int.TryParse(parity, out iParity))
                {
                    iParity = 0;
                }

                // 数据位
                int iDataBits = 0;
                if (!int.TryParse(dataBits, out iDataBits))
                {
                    iDataBits = 8;
                }

                // 停止位
                int iStopBits = 0;
                if (!int.TryParse(stopBits, out iStopBits))
                {
                    iStopBits = 1;
                }

                scannerPort = new SerialPort(portName, iBaudRate, (Parity)iParity, iDataBits, (StopBits)iStopBits);
                scannerPort.Open();
                _IsRunning = true;
                _BGThread = new Thread(new ThreadStart(BGProc));
                _BGThread.Start();
            }
            catch (Exception ex)
            { 
            }
        }

        public void Uninit()
        {
            if (null != _BGThread)
            {
                _IsRunning = false;
                //_BGThread.Interrupt();
                //_BGThread.Join();
            }
            /*
            if (null != scannerPort)
            {
                logger.Debug("Close scanner port");
                scannerPort.Close();
            }
            scannerPort = null;
             */
        }

        #region Read proc
        Thread _BGThread = null;
        bool _IsRunning = false;
        protected void BGProc()
        {
            scannerPort.ReadTimeout = 500;
            while (_IsRunning)
            {
                try
                {
                    if (OnBCStatusChanged != null)
                    {
                        OnBCStatusChanged(IsOk);
                    }

                    //解决扫描条码不去的问题，扫描枪上需添加回车作为后缀 by DongYi 2013-10-25
                    //String msg = scannerPort.ReadLine();
                    String msg = "";
                    if (scannerPort.BytesToRead > 0)
                    {
                        byte[] buf = new byte[scannerPort.BytesToRead];
                        scannerPort.Read(buf, 0, buf.Length);
                        msg = Encoding.ASCII.GetString(buf);
                        FireOnBCRead(msg);
                    }
                }
                catch (TimeoutException)
                {
                }
                catch (Exception ex)
                {
                    if (OnBCStatusChanged != null)
                    {
                        OnBCStatusChanged(false);
                    }
                }
                Thread.Sleep(300);
                //Thread.Sleep(300);
            }

            if (null != scannerPort)
            {
                //logger.Debug("Close scanner port");
                scannerPort.Close();
            }
            //logger.Debug("Scanner thread exit");
        }
        #endregion
    }
}
